package ar.edu.sovietrussia;

import java.util.ArrayList;
import java.util.List;

import org.apache.wicket.Page;
import org.apache.wicket.Session;
import org.apache.wicket.authroles.authentication.AuthenticatedWebApplication;
import org.apache.wicket.authroles.authentication.AuthenticatedWebSession;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.request.Request;
import org.apache.wicket.request.Response;
import org.apache.wicket.settings.IExceptionSettings;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.apache.wicket.spring.injection.annot.SpringComponentInjector;
import org.joda.time.DateTime;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import services.book.AuthorService;
import services.book.BookService;
import services.book.PublisherService;
import services.user.LoanService;
import services.user.PersonService;
import users.LibrarianRole;
import users.Person;
import users.UserAccount;
import users.UserRole;
import ar.edu.sovietrussia.errorpages.InternalErrorPage;
import books.Author;
import books.Book;
import books.BookInfo;
import books.Category;
import books.Publisher;
import dtos.AuthorDTO;

public class LibraryApplication extends AuthenticatedWebApplication {

    @SpringBean(name = "service.person")
    private PersonService personService;

    @SpringBean(name = "service.author")
    private AuthorService authorService;

    @SpringBean(name = "service.book")
    private BookService bookService;

    @SpringBean(name = "service.publisher")
    private PublisherService publisherService;

    @SpringBean(name = "service.loan")
    private LoanService loanService;

    @Override
    protected Class<? extends AuthenticatedWebSession> getWebSessionClass() {
        return MyAuthenticatedWebSession.class;
    }

    @Override
    public Class<? extends Page> getHomePage() {
        return LibraryApplicationPage.class;
    }

    @Override
    public void init() {
        this.getComponentInstantiationListeners().add(new SpringComponentInjector(this, this.getSpringContext(), true));
        this.initServices();
        this.configureErrorPages();
    }

    private void configureErrorPages() {
        this.getApplicationSettings().setInternalErrorPage(InternalErrorPage.class);
        this.getExceptionSettings().setUnexpectedExceptionDisplay(IExceptionSettings.SHOW_INTERNAL_ERROR_PAGE);
    }

    @Override
    protected Class<? extends WebPage> getSignInPageClass() {
        return LibraryApplicationPage.class;
    }

    @Override
    public Session newSession(final Request request, final Response response) {
        return new MyAuthenticatedWebSession(request);

    }

    public String getContextPath() {
        return this.getServletContext().getContextPath();
    }

    public void initServices() {

        String sasa = "sasa";
        ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {
                "/META-INF/spring-persistence-context.xml", "/META-INF/spring-services-context.xml" });
        this.personService = (PersonService) context.getBean("service.person");
        Person pers = new Person("Pepe", "Buenaonda", new UserAccount(sasa, sasa, LibrarianRole.getInstance()),
                "buenaonda@mail.com");
        Person pers2 = new Person("Alquilador", "Buenaonda", new UserAccount("alquilador", "1234",
                UserRole.getInstance()), "buenaonda@mail.com");

        this.personService.addPerson(pers2);
        this.personService.addPerson(pers);
        this.personService.addPerson(new Person("Jose", "Capo", new UserAccount("josecapo", sasa, UserRole
                .getInstance()), "capomail@mail.com"));
        this.personService.addPerson(new Person("Rusito", "H4cker", new UserAccount("hacker", sasa, UserRole
                .getInstance()), "soviet@mail.com"));
        this.personService.addPerson(new Person("Practica", "Tetris", new UserAccount("practica", sasa, LibrarianRole
                .getInstance()), "tetris@mail.com"));
        this.personService.addPerson(new Person("El capo", "Imaginacion", new UserAccount("tetris", sasa, UserRole
                .getInstance()), "poca@mail.com"));

        this.authorService = (AuthorService) context.getBean("service.author");
        this.authorService.addAuthorDTO(new AuthorDTO("Leo Tolstoi"));
        this.publisherService = (PublisherService) context.getBean("service.publisher");
        this.loanService = (LoanService) new ClassPathXmlApplicationContext(new String[] {
                "/META-INF/spring-persistence-context.xml", "/META-INF/spring-services-context.xml" })
                .getBean("service.loan");
        this.bookService = (BookService) context.getBean("service.book");

        Publisher publisher = new Publisher("Editorial copada");
        this.publisherService.addPublisher(publisher);
        this.publisherService.addPublisher(new Publisher("Editorial mala onda"));
        this.publisherService.addPublisher(new Publisher("Java comunista"));

        AuthorDTO author, author2, author3, author4;
        author = new AuthorDTO();
        author.setName("Autor capo");
        author2 = new AuthorDTO();
        author2.setName("Pepe imaginacion");
        author3 = new AuthorDTO();
        author3.setName("Yerbero");
        author4 = new AuthorDTO();
        author4.setName("T1000");

        this.getAuthorService().addAuthorDTO(author);
        this.getAuthorService().addAuthorDTO(author2);
        this.getAuthorService().addAuthorDTO(author3);
        this.getAuthorService().addAuthorDTO(author4);

        // GESTIONAR UN NUEVO PRESTAMO A MANOPLA
        List<Author> la = this.authorService.getAuthorsByName("Leo Tolstoi");

        // la.add(a);
        List<Category> lc = new ArrayList<Category>();
        lc.add(Category.CLASSICS);

        BookInfo b2, b3, b4, b5, b6, b7, b8, b9, b10;

        b2 = new BookInfo("War and War", "9780670034698", "Una descripcion muy bonita", publisher, la, lc);
        b2.setRegistrationDate(DateTime.now().minusDays(100));
        this.bookService.addBookInfo(b2);
        b3 = new BookInfo("War and Russia", "9780670034699", "Una descripcion muy bonita", publisher, la, lc);
        b3.setRegistrationDate(DateTime.now().minusDays(90));
        this.bookService.addBookInfo(b3);

        b4 = new BookInfo("Java en 5 mins", "9780670034001", "Sea un experto java en 5 minutos", publisher, la, lc);
        b4.setRegistrationDate(DateTime.now().minusDays(4));
        this.bookService.addBookInfo(b4);

        b5 = new BookInfo("La cara oculta del TDD", "9780670034002",
                "La verdad sobre el TDD y su secta fundamentalista", publisher, la, lc);
        b5.setRegistrationDate(DateTime.now().minusDays(1));
        this.bookService.addBookInfo(b5);

        b6 = new BookInfo("Silver Singleton Bullet", "9780670034003",
                "Descubra el poder del singleton y dispare contra los design patterns", publisher, la, lc);
        b6.setRegistrationDate(DateTime.now().minusDays(2));
        this.bookService.addBookInfo(b6);

        b7 = new BookInfo("Printline", "9780670034004", "Error? do a sysout!", publisher, la, lc);
        b7.setRegistrationDate(DateTime.now().minusDays(40));
        this.bookService.addBookInfo(b7);

        b8 = new BookInfo("Mandale alambre", "9780670034005", "10 tips que arreglan TODOS los problemas", publisher,
                la, lc);
        b8.setRegistrationDate(DateTime.now().minusDays(3));
        this.bookService.addBookInfo(b8);

        b9 = new BookInfo("Jenkins y su tirania", "9780670034006", "Desenmascarando a Jenkins Lopez y su corrupcion",
                publisher, la, lc);
        b9.setRegistrationDate(DateTime.now().minusDays(5));
        this.bookService.addBookInfo(b9);

        b10 = new BookInfo("Destino final: Refactor", "9780670034007",
                "Lucas intenta escapar de un limbo llamado Refactor", publisher, la, lc);
        b10.setRegistrationDate(DateTime.now().minusDays(6));
        this.bookService.addBookInfo(b10);

        BookInfo info1 = new BookInfo("War and Peace", "9780670034697", "Una descripcion muy bonita", publisher, la, lc);
        info1.setRegistrationDate(DateTime.now().minusDays(500));
        this.bookService.addBookInfo(info1);

        Book c1, c2, c3, c4, c5, c6, c7, c8;
        c1 = new Book(b2, 1001);
        this.bookService.addCopy(c1);
        c2 = new Book(b3, 1002);
        this.bookService.addCopy(c2);
        c8 = new Book(b3, 100677);
        this.bookService.addCopy(c8);

        c3 = new Book(b4, 1003);
        this.bookService.addCopy(c3);
        c4 = new Book(b5, 1005);
        this.bookService.addCopy(c4);
        c5 = new Book(b6, 1006);
        this.bookService.addCopy(c5);
        c6 = new Book(b7, 1007);
        this.bookService.addCopy(c6);
        c7 = new Book(b8, 1008);
        this.bookService.addCopy(c7);

        Book book = new Book(info1, 348239042);
        // Book copy2 = new Book(b2, 213123);
        Book copy3 = new Book(b3, 11111);

        this.bookService.addCopy(book);
        // this.bookService.addCopy(copy2);
        this.bookService.addCopy(copy3);

        this.loanService.newCommonLoan(info1, pers);
        this.loanService.newCommonLoan(b3, pers2);
        this.loanService.newCommonLoan(b4, pers2);
        this.loanService.newCommonLoan(b5, pers2);
        this.loanService.newCommonLoan(b3, pers);
        this.loanService.newCommonLoan(b6, pers);
    }

    public void setAuthorService(final AuthorService authorService) {
        this.authorService = authorService;
    }

    public AuthorService getAuthorService() {
        return this.authorService;
    }

    public void setBookService(final BookService bookService) {
        this.bookService = bookService;
    }

    public BookService getBookService() {
        return this.bookService;
    }

    public PersonService getPersonService() {
        return this.personService;
    }

    public void setPersonService(final PersonService personService) {
        this.personService = personService;
    }

    public final WebApplicationContext getSpringContext() {
        return WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
    }

    public void setPublisherService(final PublisherService publisherService) {
        this.publisherService = publisherService;
    }

    public PublisherService getPublisherService() {
        return this.publisherService;
    }

    public LoanService getLoanService() {
        return this.loanService;
    }

    public void setLoanService(final LoanService loanService) {
        this.loanService = loanService;
    }

}